export class Observer {
  name: string
  constructor(name: string) {
    this.name = name
  }
  update(param: any) {
    console.log(param)
  }
}
let idx: number = 0
class EventWatcher {
  eventPaylod: {
    [key: string]: any
  } = {}
  observerList: {
    [key: string]: Observer[]
  } = {}
  setData(event: string, paylod: any) {
    this.eventPaylod[event] = paylod
  }
  addObserver(event: string, ...observers: Observer[]) {
    const total_observers = Object.keys(this.observerList).includes(event)
      ? [...this.observerList[event], ...observers]
      : [...observers]
    const observers_name: string[] = []
    const res: Observer[] = []
    total_observers.forEach(item => {
      if (!observers_name.includes(item.name)) {
        observers_name.push(item.name)
        res.push(item)
      }
    })
    this.observerList[event] = [...res]
  }
  notify(event: string) {
    if (
      !Object.keys(this.observerList).includes(event) ||
      !Object.keys(this.eventPaylod).includes(event)
    ) {
      return
    }
    this.observerList[event].forEach(observer => observer.update(this.eventPaylod[event]))
  }
}
const eventWatcher = new EventWatcher()
const Install = {
  install: (Vue: any) => {
    Vue.prototype.$broadEmit = function (event: string, paylod?: any) {
      eventWatcher.setData(event, paylod)
      eventWatcher.notify(event)
    }
    Vue.prototype.$broadOn = function (event: string, callback: (param: any) => any) {
      const observer = new Observer(event + (idx + 1))
      observer.update = callback
      eventWatcher.addObserver(event, observer)
      idx += 1
    }
  }
}

export default Install
